namespace Engine
{
  using System;
  using System.ComponentModel;
  using System.Globalization;
  using System.Runtime.InteropServices;

  [Serializable, StructLayout(LayoutKind.Sequential)]
    public struct DQuaternion : IEquatable<DQuaternion>
  {
      public double X;
      public double Y;
      public double Z;
      public double W;
    private static DQuaternion _identity;
    public static DQuaternion Identity
    {
      get
      {
        return _identity;
      }
    }
    public DQuaternion(double x, double y, double z, double w)
    {
      this.X = x;
      this.Y = y;
      this.Z = z;
      this.W = w;
    }
    
    public DQuaternion(DVector3 vectorPart, double scalarPart)
    {
      this.X = vectorPart.X;
      this.Y = vectorPart.Y;
      this.Z = vectorPart.Z;
      this.W = scalarPart;
    }
    
    public override string ToString()
    {
      CultureInfo currentCulture = CultureInfo.CurrentCulture;
      return string.Format(currentCulture, "{{X:{0} Y:{1} Z:{2} W:{3}}}", new object[] { this.X.ToString(currentCulture), this.Y.ToString(currentCulture), this.Z.ToString(currentCulture), this.W.ToString(currentCulture) });
    }
    
    public bool Equals(DQuaternion other)
    {
      return ((((this.X == other.X) && (this.Y == other.Y)) && (this.Z == other.Z)) && (this.W == other.W));
    }
    
    public override bool Equals(object obj)
    {
      bool flag = false;
      if (obj is DQuaternion)
      {
        flag = this.Equals((DQuaternion) obj);
      }
      return flag;
    }
    
    public override int GetHashCode()
    {
      return (((this.X.GetHashCode() + this.Y.GetHashCode()) + this.Z.GetHashCode()) + this.W.GetHashCode());
    }
    
    public double LengthSquared()
    {
      return ((((this.X * this.X) + (this.Y * this.Y)) + (this.Z * this.Z)) + (this.W * this.W));
    }
    
    public double Length()
    {
      double num = (((this.X * this.X) + (this.Y * this.Y)) + (this.Z * this.Z)) + (this.W * this.W);
      return  Math.Sqrt( num);
    }
    
    public void Normalize()
    {
      double num2 = (((this.X * this.X) + (this.Y * this.Y)) + (this.Z * this.Z)) + (this.W * this.W);
      double num = 1f / ( Math.Sqrt( num2));
      this.X *= num;
      this.Y *= num;
      this.Z *= num;
      this.W *= num;
    }
    
    public static DQuaternion Normalize(DQuaternion quaternion)
    {
      DQuaternion quaternion2;
      double num2 = (((quaternion.X * quaternion.X) + (quaternion.Y * quaternion.Y)) + (quaternion.Z * quaternion.Z)) + (quaternion.W * quaternion.W);
      double num = 1f / ( Math.Sqrt( num2));
      quaternion2.X = quaternion.X * num;
      quaternion2.Y = quaternion.Y * num;
      quaternion2.Z = quaternion.Z * num;
      quaternion2.W = quaternion.W * num;
      return quaternion2;
    }
    
    public static void Normalize(ref DQuaternion quaternion, out DQuaternion result)
    {
      double num2 = (((quaternion.X * quaternion.X) + (quaternion.Y * quaternion.Y)) + (quaternion.Z * quaternion.Z)) + (quaternion.W * quaternion.W);
      double num = 1f / ( Math.Sqrt( num2));
      result.X = quaternion.X * num;
      result.Y = quaternion.Y * num;
      result.Z = quaternion.Z * num;
      result.W = quaternion.W * num;
    }
    
    public void Conjugate()
    {
      this.X = -this.X;
      this.Y = -this.Y;
      this.Z = -this.Z;
    }
    
    public static DQuaternion Conjugate(DQuaternion value)
    {
      DQuaternion quaternion;
      quaternion.X = -value.X;
      quaternion.Y = -value.Y;
      quaternion.Z = -value.Z;
      quaternion.W = value.W;
      return quaternion;
    }
    
    public static void Conjugate(ref DQuaternion value, out DQuaternion result)
    {
      result.X = -value.X;
      result.Y = -value.Y;
      result.Z = -value.Z;
      result.W = value.W;
    }
    
    public static DQuaternion Inverse(DQuaternion quaternion)
    {
      DQuaternion quaternion2;
      double num2 = (((quaternion.X * quaternion.X) + (quaternion.Y * quaternion.Y)) + (quaternion.Z * quaternion.Z)) + (quaternion.W * quaternion.W);
      double num = 1f / num2;
      quaternion2.X = -quaternion.X * num;
      quaternion2.Y = -quaternion.Y * num;
      quaternion2.Z = -quaternion.Z * num;
      quaternion2.W = quaternion.W * num;
      return quaternion2;
    }
    
    public static void Inverse(ref DQuaternion quaternion, out DQuaternion result)
    {
        double num2 = (((quaternion.X * quaternion.X) + (quaternion.Y * quaternion.Y)) + (quaternion.Z * quaternion.Z)) + (quaternion.W * quaternion.W);
      double num = 1f / num2;
      result.X = -quaternion.X * num;
      result.Y = -quaternion.Y * num;
      result.Z = -quaternion.Z * num;
      result.W = quaternion.W * num;
    }

    public static DQuaternion CreateFromAxisAngle(DVector3 axis, double angle)
    {
      DQuaternion quaternion;
      double num2 = angle * 0.5f;
      double num = Math.Sin(num2);
      double num3 = Math.Cos(num2);
      quaternion.X = axis.X * num;
      quaternion.Y = axis.Y * num;
      quaternion.Z = axis.Z * num;
      quaternion.W = num3;
      return quaternion;
    }

    public static void CreateFromAxisAngle(ref DVector3 axis, double angle, out DQuaternion result)
    {
        double num2 = angle * 0.5f;
        double num = Math.Sin(num2);
      double num3 = Math.Cos(num2);
      result.X = axis.X * num;
      result.Y = axis.Y * num;
      result.Z = axis.Z * num;
      result.W = num3;
    }

    public static DQuaternion CreateFromYawPitchRoll(double yaw, double pitch, double roll)
    {
      DQuaternion quaternion;
      double num9 = roll * 0.5f;
      double num6 = (double)Math.Sin((double)num9);
      double num5 = (double)Math.Cos((double)num9);
      double num8 = pitch * 0.5f;
      double num4 = (double)Math.Sin((double)num8);
      double num3 = (double)Math.Cos((double)num8);
      double num7 = yaw * 0.5f;
      double num2 = (double)Math.Sin((double)num7);
      double num = (double)Math.Cos((double)num7);
      quaternion.X = ((num * num4) * num5) + ((num2 * num3) * num6);
      quaternion.Y = ((num2 * num3) * num5) - ((num * num4) * num6);
      quaternion.Z = ((num * num3) * num6) - ((num2 * num4) * num5);
      quaternion.W = ((num * num3) * num5) + ((num2 * num4) * num6);
      return quaternion;
    }

    public static void CreateFromYawPitchRoll(double yaw, double pitch, double roll, out DQuaternion result)
    {
        double num9 = roll * 0.5f;
        double num6 = (double)Math.Sin((double)num9);
        double num5 = (double)Math.Cos((double)num9);
        double num8 = pitch * 0.5f;
        double num4 = (double)Math.Sin((double)num8);
        double num3 = (double)Math.Cos((double)num8);
        double num7 = yaw * 0.5f;
        double num2 = (double)Math.Sin((double)num7);
        double num = (double)Math.Cos((double)num7);
      result.X = ((num * num4) * num5) + ((num2 * num3) * num6);
      result.Y = ((num2 * num3) * num5) - ((num * num4) * num6);
      result.Z = ((num * num3) * num6) - ((num2 * num4) * num5);
      result.W = ((num * num3) * num5) + ((num2 * num4) * num6);
    }
    
    public static DQuaternion CreateFromRotationMatrix(DMatrix matrix)
    {
        double num8 = (matrix.M11 + matrix.M22) + matrix.M33;
      DQuaternion quaternion = new DQuaternion();
      if (num8 > 0f)
      {
          double num = Math.Sqrt((num8 + 1f));
        quaternion.W = num * 0.5f;
        num = 0.5f / num;
        quaternion.X = (matrix.M23 - matrix.M32) * num;
        quaternion.Y = (matrix.M31 - matrix.M13) * num;
        quaternion.Z = (matrix.M12 - matrix.M21) * num;
        return quaternion;
      }
      if ((matrix.M11 >= matrix.M22) && (matrix.M11 >= matrix.M33))
      {
          double num7 = Math.Sqrt((((1f + matrix.M11) - matrix.M22) - matrix.M33));
          double num4 = 0.5f / num7;
        quaternion.X = 0.5f * num7;
        quaternion.Y = (matrix.M12 + matrix.M21) * num4;
        quaternion.Z = (matrix.M13 + matrix.M31) * num4;
        quaternion.W = (matrix.M23 - matrix.M32) * num4;
        return quaternion;
      }
      if (matrix.M22 > matrix.M33)
      {
          double num6 = Math.Sqrt((((1f + matrix.M22) - matrix.M11) - matrix.M33));
          double num3 = 0.5f / num6;
        quaternion.X = (matrix.M21 + matrix.M12) * num3;
        quaternion.Y = 0.5f * num6;
        quaternion.Z = (matrix.M32 + matrix.M23) * num3;
        quaternion.W = (matrix.M31 - matrix.M13) * num3;
        return quaternion;
      }
      double num5 = Math.Sqrt((((1f + matrix.M33) - matrix.M11) - matrix.M22));
      double num2 = 0.5f / num5;
      quaternion.X = (matrix.M31 + matrix.M13) * num2;
      quaternion.Y = (matrix.M32 + matrix.M23) * num2;
      quaternion.Z = 0.5f * num5;
      quaternion.W = (matrix.M12 - matrix.M21) * num2;
      return quaternion;
    }
    
    public static void CreateFromRotationMatrix(ref DMatrix matrix, out DQuaternion result)
    {
        double num8 = (matrix.M11 + matrix.M22) + matrix.M33;
      if (num8 > 0f)
      {
          double num = Math.Sqrt((num8 + 1f));
        result.W = num * 0.5f;
        num = 0.5f / num;
        result.X = (matrix.M23 - matrix.M32) * num;
        result.Y = (matrix.M31 - matrix.M13) * num;
        result.Z = (matrix.M12 - matrix.M21) * num;
      }
      else if ((matrix.M11 >= matrix.M22) && (matrix.M11 >= matrix.M33))
      {
          double num7 = Math.Sqrt((((1f + matrix.M11) - matrix.M22) - matrix.M33));
          double num4 = 0.5f / num7;
        result.X = 0.5f * num7;
        result.Y = (matrix.M12 + matrix.M21) * num4;
        result.Z = (matrix.M13 + matrix.M31) * num4;
        result.W = (matrix.M23 - matrix.M32) * num4;
      }
      else if (matrix.M22 > matrix.M33)
      {
          double num6 = Math.Sqrt((((1f + matrix.M22) - matrix.M11) - matrix.M33));
          double num3 = 0.5f / num6;
        result.X = (matrix.M21 + matrix.M12) * num3;
        result.Y = 0.5f * num6;
        result.Z = (matrix.M32 + matrix.M23) * num3;
        result.W = (matrix.M31 - matrix.M13) * num3;
      }
      else
      {
          double num5 = Math.Sqrt((((1f + matrix.M33) - matrix.M11) - matrix.M22));
        double num2 = 0.5f / num5;
        result.X = (matrix.M31 + matrix.M13) * num2;
        result.Y = (matrix.M32 + matrix.M23) * num2;
        result.Z = 0.5f * num5;
        result.W = (matrix.M12 - matrix.M21) * num2;
      }
    }

    public static double Dot(DQuaternion quaternion1, DQuaternion quaternion2)
    {
      return ((((quaternion1.X * quaternion2.X) + (quaternion1.Y * quaternion2.Y)) + (quaternion1.Z * quaternion2.Z)) + (quaternion1.W * quaternion2.W));
    }

    public static void Dot(ref DQuaternion quaternion1, ref DQuaternion quaternion2, out double result)
    {
      result = (((quaternion1.X * quaternion2.X) + (quaternion1.Y * quaternion2.Y)) + (quaternion1.Z * quaternion2.Z)) + (quaternion1.W * quaternion2.W);
    }

    public static DQuaternion Slerp(DQuaternion quaternion1, DQuaternion quaternion2, double amount)
    {
        double num2;
      double num3;
      DQuaternion quaternion;
      double num = amount;
      double num4 = (((quaternion1.X * quaternion2.X) + (quaternion1.Y * quaternion2.Y)) + (quaternion1.Z * quaternion2.Z)) + (quaternion1.W * quaternion2.W);
      bool flag = false;
      if (num4 < 0f)
      {
        flag = true;
        num4 = -num4;
      }
      if (num4 > 0.999999f)
      {
        num3 = 1f - num;
        num2 = flag ? -num : num;
      }
      else
      {
          double num5 = Math.Acos(num4);
          double num6 = (1.0 / Math.Sin(num5));
        num3 = ( Math.Sin( ((1f - num) * num5))) * num6;
        num2 = flag ? (( -Math.Sin( (num * num5))) * num6) : (( Math.Sin( (num * num5))) * num6);
      }
      quaternion.X = (num3 * quaternion1.X) + (num2 * quaternion2.X);
      quaternion.Y = (num3 * quaternion1.Y) + (num2 * quaternion2.Y);
      quaternion.Z = (num3 * quaternion1.Z) + (num2 * quaternion2.Z);
      quaternion.W = (num3 * quaternion1.W) + (num2 * quaternion2.W);
      return quaternion;
    }

    public static void Slerp(ref DQuaternion quaternion1, ref DQuaternion quaternion2, double amount, out DQuaternion result)
    {
        double num2;
      double num3;
      double num = amount;
      double num4 = (((quaternion1.X * quaternion2.X) + (quaternion1.Y * quaternion2.Y)) + (quaternion1.Z * quaternion2.Z)) + (quaternion1.W * quaternion2.W);
      bool flag = false;
      if (num4 < 0f)
      {
        flag = true;
        num4 = -num4;
      }
      if (num4 > 0.999999f)
      {
        num3 = 1f - num;
        num2 = flag ? -num : num;
      }
      else
      {
          double num5 = Math.Acos(num4);
        double num6 = (1.0 / Math.Sin(num5));
        num3 = ( Math.Sin((double) ((1f - num) * num5))) * num6;
        num2 = flag ? (( -Math.Sin( (num * num5))) * num6) : (( Math.Sin( (num * num5))) * num6);
      }
      result.X = (num3 * quaternion1.X) + (num2 * quaternion2.X);
      result.Y = (num3 * quaternion1.Y) + (num2 * quaternion2.Y);
      result.Z = (num3 * quaternion1.Z) + (num2 * quaternion2.Z);
      result.W = (num3 * quaternion1.W) + (num2 * quaternion2.W);
    }

    public static DQuaternion Lerp(DQuaternion quaternion1, DQuaternion quaternion2, double amount)
    {
        double num = amount;
        double num2 = 1f - num;
      DQuaternion quaternion = new DQuaternion();
      double num5 = (((quaternion1.X * quaternion2.X) + (quaternion1.Y * quaternion2.Y)) + (quaternion1.Z * quaternion2.Z)) + (quaternion1.W * quaternion2.W);
      if (num5 >= 0f)
      {
        quaternion.X = (num2 * quaternion1.X) + (num * quaternion2.X);
        quaternion.Y = (num2 * quaternion1.Y) + (num * quaternion2.Y);
        quaternion.Z = (num2 * quaternion1.Z) + (num * quaternion2.Z);
        quaternion.W = (num2 * quaternion1.W) + (num * quaternion2.W);
      }
      else
      {
        quaternion.X = (num2 * quaternion1.X) - (num * quaternion2.X);
        quaternion.Y = (num2 * quaternion1.Y) - (num * quaternion2.Y);
        quaternion.Z = (num2 * quaternion1.Z) - (num * quaternion2.Z);
        quaternion.W = (num2 * quaternion1.W) - (num * quaternion2.W);
      }
      double num4 = (((quaternion.X * quaternion.X) + (quaternion.Y * quaternion.Y)) + (quaternion.Z * quaternion.Z)) + (quaternion.W * quaternion.W);
      double num3 = 1f / (Math.Sqrt(num4));
      quaternion.X *= num3;
      quaternion.Y *= num3;
      quaternion.Z *= num3;
      quaternion.W *= num3;
      return quaternion;
    }

    public static void Lerp(ref DQuaternion quaternion1, ref DQuaternion quaternion2, double amount, out DQuaternion result)
    {
        double num = amount;
        double num2 = 1f - num;
        double num5 = (((quaternion1.X * quaternion2.X) + (quaternion1.Y * quaternion2.Y)) + (quaternion1.Z * quaternion2.Z)) + (quaternion1.W * quaternion2.W);
      if (num5 >= 0f)
      {
        result.X = (num2 * quaternion1.X) + (num * quaternion2.X);
        result.Y = (num2 * quaternion1.Y) + (num * quaternion2.Y);
        result.Z = (num2 * quaternion1.Z) + (num * quaternion2.Z);
        result.W = (num2 * quaternion1.W) + (num * quaternion2.W);
      }
      else
      {
        result.X = (num2 * quaternion1.X) - (num * quaternion2.X);
        result.Y = (num2 * quaternion1.Y) - (num * quaternion2.Y);
        result.Z = (num2 * quaternion1.Z) - (num * quaternion2.Z);
        result.W = (num2 * quaternion1.W) - (num * quaternion2.W);
      }
      double num4 = (((result.X * result.X) + (result.Y * result.Y)) + (result.Z * result.Z)) + (result.W * result.W);
      double num3 = 1f / (Math.Sqrt(num4));
      result.X *= num3;
      result.Y *= num3;
      result.Z *= num3;
      result.W *= num3;
    }
    
    public static DQuaternion Concatenate(DQuaternion value1, DQuaternion value2)
    {
      DQuaternion quaternion;
      double x = value2.X;
      double y = value2.Y;
      double z = value2.Z;
      double w = value2.W;
      double num4 = value1.X;
      double num3 = value1.Y;
      double num2 = value1.Z;
      double num = value1.W;
      double num12 = (y * num2) - (z * num3);
      double num11 = (z * num4) - (x * num2);
      double num10 = (x * num3) - (y * num4);
      double num9 = ((x * num4) + (y * num3)) + (z * num2);
      quaternion.X = ((x * num) + (num4 * w)) + num12;
      quaternion.Y = ((y * num) + (num3 * w)) + num11;
      quaternion.Z = ((z * num) + (num2 * w)) + num10;
      quaternion.W = (w * num) - num9;
      return quaternion;
    }
    
    public static void Concatenate(ref DQuaternion value1, ref DQuaternion value2, out DQuaternion result)
    {
        double x = value2.X;
      double y = value2.Y;
      double z = value2.Z;
      double w = value2.W;
      double num4 = value1.X;
      double num3 = value1.Y;
      double num2 = value1.Z;
      double num = value1.W;
      double num12 = (y * num2) - (z * num3);
      double num11 = (z * num4) - (x * num2);
      double num10 = (x * num3) - (y * num4);
      double num9 = ((x * num4) + (y * num3)) + (z * num2);
      result.X = ((x * num) + (num4 * w)) + num12;
      result.Y = ((y * num) + (num3 * w)) + num11;
      result.Z = ((z * num) + (num2 * w)) + num10;
      result.W = (w * num) - num9;
    }
    
    public static DQuaternion Negate(DQuaternion quaternion)
    {
      DQuaternion quaternion2;
      quaternion2.X = -quaternion.X;
      quaternion2.Y = -quaternion.Y;
      quaternion2.Z = -quaternion.Z;
      quaternion2.W = -quaternion.W;
      return quaternion2;
    }
    
    public static void Negate(ref DQuaternion quaternion, out DQuaternion result)
    {
      result.X = -quaternion.X;
      result.Y = -quaternion.Y;
      result.Z = -quaternion.Z;
      result.W = -quaternion.W;
    }
    
    public static DQuaternion Add(DQuaternion quaternion1, DQuaternion quaternion2)
    {
      DQuaternion quaternion;
      quaternion.X = quaternion1.X + quaternion2.X;
      quaternion.Y = quaternion1.Y + quaternion2.Y;
      quaternion.Z = quaternion1.Z + quaternion2.Z;
      quaternion.W = quaternion1.W + quaternion2.W;
      return quaternion;
    }
    
    public static void Add(ref DQuaternion quaternion1, ref DQuaternion quaternion2, out DQuaternion result)
    {
      result.X = quaternion1.X + quaternion2.X;
      result.Y = quaternion1.Y + quaternion2.Y;
      result.Z = quaternion1.Z + quaternion2.Z;
      result.W = quaternion1.W + quaternion2.W;
    }
    
    public static DQuaternion Subtract(DQuaternion quaternion1, DQuaternion quaternion2)
    {
      DQuaternion quaternion;
      quaternion.X = quaternion1.X - quaternion2.X;
      quaternion.Y = quaternion1.Y - quaternion2.Y;
      quaternion.Z = quaternion1.Z - quaternion2.Z;
      quaternion.W = quaternion1.W - quaternion2.W;
      return quaternion;
    }
    
    public static void Subtract(ref DQuaternion quaternion1, ref DQuaternion quaternion2, out DQuaternion result)
    {
      result.X = quaternion1.X - quaternion2.X;
      result.Y = quaternion1.Y - quaternion2.Y;
      result.Z = quaternion1.Z - quaternion2.Z;
      result.W = quaternion1.W - quaternion2.W;
    }
    
    public static DQuaternion Multiply(DQuaternion quaternion1, DQuaternion quaternion2)
    {
      DQuaternion quaternion;
      double x = quaternion1.X;
      double y = quaternion1.Y;
      double z = quaternion1.Z;
      double w = quaternion1.W;
      double num4 = quaternion2.X;
      double num3 = quaternion2.Y;
      double num2 = quaternion2.Z;
      double num = quaternion2.W;
      double num12 = (y * num2) - (z * num3);
      double num11 = (z * num4) - (x * num2);
      double num10 = (x * num3) - (y * num4);
      double num9 = ((x * num4) + (y * num3)) + (z * num2);
      quaternion.X = ((x * num) + (num4 * w)) + num12;
      quaternion.Y = ((y * num) + (num3 * w)) + num11;
      quaternion.Z = ((z * num) + (num2 * w)) + num10;
      quaternion.W = (w * num) - num9;
      return quaternion;
    }
    
    public static void Multiply(ref DQuaternion quaternion1, ref DQuaternion quaternion2, out DQuaternion result)
    {
        double x = quaternion1.X;
      double y = quaternion1.Y;
      double z = quaternion1.Z;
      double w = quaternion1.W;
      double num4 = quaternion2.X;
      double num3 = quaternion2.Y;
      double num2 = quaternion2.Z;
      double num = quaternion2.W;
      double num12 = (y * num2) - (z * num3);
      double num11 = (z * num4) - (x * num2);
      double num10 = (x * num3) - (y * num4);
      double num9 = ((x * num4) + (y * num3)) + (z * num2);
      result.X = ((x * num) + (num4 * w)) + num12;
      result.Y = ((y * num) + (num3 * w)) + num11;
      result.Z = ((z * num) + (num2 * w)) + num10;
      result.W = (w * num) - num9;
    }

    public static DQuaternion Multiply(DQuaternion quaternion1, double scaleFactor)
    {
      DQuaternion quaternion;
      quaternion.X = quaternion1.X * scaleFactor;
      quaternion.Y = quaternion1.Y * scaleFactor;
      quaternion.Z = quaternion1.Z * scaleFactor;
      quaternion.W = quaternion1.W * scaleFactor;
      return quaternion;
    }

    public static void Multiply(ref DQuaternion quaternion1, double scaleFactor, out DQuaternion result)
    {
      result.X = quaternion1.X * scaleFactor;
      result.Y = quaternion1.Y * scaleFactor;
      result.Z = quaternion1.Z * scaleFactor;
      result.W = quaternion1.W * scaleFactor;
    }
    
    public static DQuaternion Divide(DQuaternion quaternion1, DQuaternion quaternion2)
    {
      DQuaternion quaternion;
      double x = quaternion1.X;
      double y = quaternion1.Y;
      double z = quaternion1.Z;
      double w = quaternion1.W;
      double num14 = (((quaternion2.X * quaternion2.X) + (quaternion2.Y * quaternion2.Y)) + (quaternion2.Z * quaternion2.Z)) + (quaternion2.W * quaternion2.W);
      double num5 = 1f / num14;
      double num4 = -quaternion2.X * num5;
      double num3 = -quaternion2.Y * num5;
      double num2 = -quaternion2.Z * num5;
      double num = quaternion2.W * num5;
      double num13 = (y * num2) - (z * num3);
      double num12 = (z * num4) - (x * num2);
      double num11 = (x * num3) - (y * num4);
      double num10 = ((x * num4) + (y * num3)) + (z * num2);
      quaternion.X = ((x * num) + (num4 * w)) + num13;
      quaternion.Y = ((y * num) + (num3 * w)) + num12;
      quaternion.Z = ((z * num) + (num2 * w)) + num11;
      quaternion.W = (w * num) - num10;
      return quaternion;
    }
    
    public static void Divide(ref DQuaternion quaternion1, ref DQuaternion quaternion2, out DQuaternion result)
    {
        double x = quaternion1.X;
        double y = quaternion1.Y;
      double z = quaternion1.Z;
      double w = quaternion1.W;
      double num14 = (((quaternion2.X * quaternion2.X) + (quaternion2.Y * quaternion2.Y)) + (quaternion2.Z * quaternion2.Z)) + (quaternion2.W * quaternion2.W);
      double num5 = 1f / num14;
      double num4 = -quaternion2.X * num5;
      double num3 = -quaternion2.Y * num5;
      double num2 = -quaternion2.Z * num5;
      double num = quaternion2.W * num5;
      double num13 = (y * num2) - (z * num3);
      double num12 = (z * num4) - (x * num2);
      double num11 = (x * num3) - (y * num4);
      double num10 = ((x * num4) + (y * num3)) + (z * num2);
      result.X = ((x * num) + (num4 * w)) + num13;
      result.Y = ((y * num) + (num3 * w)) + num12;
      result.Z = ((z * num) + (num2 * w)) + num11;
      result.W = (w * num) - num10;
    }
    
    public static DQuaternion operator -(DQuaternion quaternion)
    {
      DQuaternion quaternion2;
      quaternion2.X = -quaternion.X;
      quaternion2.Y = -quaternion.Y;
      quaternion2.Z = -quaternion.Z;
      quaternion2.W = -quaternion.W;
      return quaternion2;
    }
    
    public static bool operator ==(DQuaternion quaternion1, DQuaternion quaternion2)
    {
      return ((((quaternion1.X == quaternion2.X) && (quaternion1.Y == quaternion2.Y)) && (quaternion1.Z == quaternion2.Z)) && (quaternion1.W == quaternion2.W));
    }
    
    public static bool operator !=(DQuaternion quaternion1, DQuaternion quaternion2)
    {
      if (((quaternion1.X == quaternion2.X) && (quaternion1.Y == quaternion2.Y)) && (quaternion1.Z == quaternion2.Z))
      {
        return !(quaternion1.W == quaternion2.W);
      }
      return true;
    }
    
    public static DQuaternion operator +(DQuaternion quaternion1, DQuaternion quaternion2)
    {
      DQuaternion quaternion;
      quaternion.X = quaternion1.X + quaternion2.X;
      quaternion.Y = quaternion1.Y + quaternion2.Y;
      quaternion.Z = quaternion1.Z + quaternion2.Z;
      quaternion.W = quaternion1.W + quaternion2.W;
      return quaternion;
    }
    
    public static DQuaternion operator -(DQuaternion quaternion1, DQuaternion quaternion2)
    {
      DQuaternion quaternion;
      quaternion.X = quaternion1.X - quaternion2.X;
      quaternion.Y = quaternion1.Y - quaternion2.Y;
      quaternion.Z = quaternion1.Z - quaternion2.Z;
      quaternion.W = quaternion1.W - quaternion2.W;
      return quaternion;
    }
    
    public static DQuaternion operator *(DQuaternion quaternion1, DQuaternion quaternion2)
    {
      DQuaternion quaternion;
      double x = quaternion1.X;
      double y = quaternion1.Y;
      double z = quaternion1.Z;
      double w = quaternion1.W;
      double num4 = quaternion2.X;
      double num3 = quaternion2.Y;
      double num2 = quaternion2.Z;
      double num = quaternion2.W;
      double num12 = (y * num2) - (z * num3);
      double num11 = (z * num4) - (x * num2);
      double num10 = (x * num3) - (y * num4);
      double num9 = ((x * num4) + (y * num3)) + (z * num2);
      quaternion.X = ((x * num) + (num4 * w)) + num12;
      quaternion.Y = ((y * num) + (num3 * w)) + num11;
      quaternion.Z = ((z * num) + (num2 * w)) + num10;
      quaternion.W = (w * num) - num9;
      return quaternion;
    }

    public static DQuaternion operator *(DQuaternion quaternion1, double scaleFactor)
    {
      DQuaternion quaternion;
      quaternion.X = quaternion1.X * scaleFactor;
      quaternion.Y = quaternion1.Y * scaleFactor;
      quaternion.Z = quaternion1.Z * scaleFactor;
      quaternion.W = quaternion1.W * scaleFactor;
      return quaternion;
    }
    
    public static DQuaternion operator /(DQuaternion quaternion1, DQuaternion quaternion2)
    {
      DQuaternion quaternion;
      double x = quaternion1.X;
      double y = quaternion1.Y;
      double z = quaternion1.Z;
      double w = quaternion1.W;
      double num14 = (((quaternion2.X * quaternion2.X) + (quaternion2.Y * quaternion2.Y)) + (quaternion2.Z * quaternion2.Z)) + (quaternion2.W * quaternion2.W);
      double num5 = 1f / num14;
      double num4 = -quaternion2.X * num5;
      double num3 = -quaternion2.Y * num5;
      double num2 = -quaternion2.Z * num5;
      double num = quaternion2.W * num5;
      double num13 = (y * num2) - (z * num3);
      double num12 = (z * num4) - (x * num2);
      double num11 = (x * num3) - (y * num4);
      double num10 = ((x * num4) + (y * num3)) + (z * num2);
      quaternion.X = ((x * num) + (num4 * w)) + num13;
      quaternion.Y = ((y * num) + (num3 * w)) + num12;
      quaternion.Z = ((z * num) + (num2 * w)) + num11;
      quaternion.W = (w * num) - num10;
      return quaternion;
    }
    
    static DQuaternion()
    {
      _identity = new DQuaternion(0f, 0f, 0f, 1f);
    }
  }
}
